#pragma once

#ifndef NOT_USEQT
#include <QJsonDocument>
#endif

#include <cstddef>

#include "core.h"

namespace CoreUtility {
#ifndef NOT_USEQT
QJsonDocument S_CORE_EXPORT openJsonDoc(const QString& filePath);
#endif
int S_CORE_EXPORT field_copy(char* field, int capcity, const char* source,
                             int len = -1);
int S_CORE_EXPORT field_copyw(wchar_t* field, int capcity,
                              const wchar_t* source, int len = -1);

int S_CORE_EXPORT qbPrintF(char* const _Buffer, size_t const _BufferCount,
                           size_t const _MaxCount, char const* const _Format,
                           ...);
}  // namespace CoreUtility

#ifndef WIN32
#ifndef _countof
#define _countof(arr) (sizeof(arr) / sizeof(arr)[0])
#endif
#endif

#define FIELDCOPY(field, src) \
  CoreUtility::field_copy(field, _countof(field), src)
#define FIELDCOPYW(field, src) \
  CoreUtility::field_copyw(field, _countof(field), src)
#define FIELDCOPYN(field, bytes, src) CoreUtility::field_copy(field, bytes, src)
#define FIELDCOPYN_NOZEROEND(field, src, len) \
  CoreUtility::field_copy(field, _countof(field), src, len)
#define FIELDCOPYWN(field, ncount, src) \
  CoreUtility::field_copyw(field, ncount, src)

// TODO: QT?
#ifdef WIN32
#define FMTBUF(buf, fmt, ...) \
  _snprintf_s(buf, _countof(buf), _TRUNCATE, fmt, ##__VA_ARGS__)
#define FMTBUFN(buf, capcity, fmt, ...) \
  CoreUtility::qbPrintF(buf, capcity, _TRUNCATE, fmt, ##__VA_ARGS__)
#define FMTBUFW(buf, fmt, ...) \
  _snwprintf_s(buf, _countof(buf), _TRUNCATE, fmt, ##__VA_ARGS__)
#define FMTBUFWN(buf, capcity, fmt, ...) \
  _snwprintf_s(buf, capcity, _TRUNCATE, fmt, ##__VA_ARGS__)

#else
#define FMTBUF(buf, fmt, ...) snprintf(buf, _countof(buf), fmt, ##__VA_ARGS__)
#define FMTBUFN(buf, capcity, fmt, ...) \
  snprintf(buf, capcity, fmt, ##__VA_ARGS__)
#define FMTBUFW(buf, fmt, ...) swprintf(buf, _countof(buf), fmt, ##__VA_ARGS__)
#define FMTBUFWN(buf, capcity, fmt, ...) \
  swprintf(buf, capcity, fmt, ##__VA_ARGS__)
#endif
